package com.strato.mvc.api.v1_0_0.control;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.osgi.framework.Bundle;

public class StaticResource {
	
	public static void delegateToWebApp(HttpServletRequest request, HttpServletResponse response, Bundle bundle) {
		delegateToWebApp(request, response, bundle, "/");
	}
	public static void delegateToWebApp(HttpServletRequest request, HttpServletResponse response, Bundle bundle, String bundlePath) {
		if(bundle==null){
			try {
				response.sendError(HttpServletResponse.SC_NOT_FOUND);
			} catch (IOException e) {
				e.printStackTrace();
			}
			return;
		}
		String uri=request.getRequestURI();
		String contextPath=request.getContextPath();
		int index=uri.indexOf(contextPath);
		if(index!=-1){
			uri=uri.substring(index+contextPath.length());
		}
		if(bundlePath!=null&&uri.startsWith(bundlePath)){
			uri=uri.substring(bundlePath.length());
		}
//		if(uri.startsWith("/")){
//			uri=uri.substring(1);
//		}
		if(fobbiden(uri)){
			try {
				response.sendError(403);
			} catch (IOException e) {
				e.printStackTrace();
			}
			return;
		}
		URL url = bundle.getResource(uri);
		if(url==null){
			try {
				response.sendError(404);
			} catch (IOException e) {
				e.printStackTrace();
			}
			return;
		}
		int expireSeconds=60*60;
		response.setHeader("Cache-Control", "public,max-age="+expireSeconds);
		response.setDateHeader("Last-Modified", bundle.getLastModified());
		response.setHeader("ETag", ""+bundle.getLastModified());
		response.setDateHeader("Expires", System.currentTimeMillis()+expireSeconds*1000);
		response.setStatus(HttpServletResponse.SC_OK);
		ServletOutputStream os;
		InputStream is = null;
		try {
			is=url.openStream();
			os = response.getOutputStream();
			IOUtils.copyLarge(url.openStream(), os);
			os.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(is!=null){
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	private static boolean fobbiden(String uri) {
		String[] fobbidenSuffixes=new String[]{".class",".vm",".mf",".properties",".java"};
		for(String suffix:fobbidenSuffixes){
			if(uri.endsWith(suffix)){
				return true;
			}
		}
		String[] fobbidenKeywords=new String[]{"META-INF"};
		for(String keyword:fobbidenKeywords){
			if(uri.indexOf(keyword)!=-1){
				return true;
			}
		}
		return false;
	}

}
